<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2021.3.18
 * Time: 14:25
 */

interface Log {
    public function write();
}

class FileLog implements Log
{
    public function write()
    {
        echo "echo file..log ...\r\n";
    }
}


class DatabaseLog implements  Log
{
    public function write()
    {
        echo "echo database..log ...\r\n";
    }
}

class User {
    protected $log;

    public function __construct(FileLog $log)
    {
        $this->log = $log;
    }

    public function login() {
        $this->log->write();
    }
}

function make($concrete)
{
    $reflector = new ReflectionClass($concrete);
    $constructor = $reflector->getConstructor();
    if(is_null($constructor)) {
        return $reflector->newInstance();
    } else {
        $dependencies = $constructor->getParameters();
        $instances = getDependencies($dependencies);
        return $reflector->newInstanceArgs($instances);
    }
}

function getDependencies($parameters)
{
    $dependencies = [];
    foreach ($parameters as $parameter) {
        $dependencies[] = make($parameter->getClass()->name);
    }
    return $dependencies;
}

$user = make('User');
$user->login();
exit;

/**
 * 简单的容器创建
 *
 * 1、需要了解 ReflectionClass 这个类。
 *      getConstructor() 获取传入构造函数
 *      newInstance()  实例化一个类
 *      getParameters() 获取构造函数里的变量
 *      getClass() 获取变量的类名
 *
 * 这里有一个递归函数，因为构造函数可以传参，所以解析了构造函数里参数，参数又是一个类
 * 类中又有构造函数，依次不断的递归，直到无
 */